package com.yx.udp;

import android.net.Uri;
import android.util.Log;
import android.view.TextureView;
import android.view.View;
import org.videolan.libvlc.Media;

import com.yx.udp.util.Crc16Utils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;
import org.videolan.libvlc.interfaces.IVLCVout;
public class UdpHandshakeParser {


    // 协议常量
    private static final int HEADER_LOW = 0x55;
    private static final int HEADER_HIGH = 0xAA;
    private static final int CMD_ID = 0x0101;
    private static final int CMD_TYPE = 0x02;
    private static final int PACKET_LENGTH = 85;

    public static HandshakePacket parse(byte[] data) throws InvalidPacketException {
        Log.d("TAG", "parse22: "+data.length);
        if (data == null || data.length != PACKET_LENGTH) {
//            throw new InvalidPacketException("Invalid packet length");
        }
        // 4. 解析主要数据
        HandshakePacket packet = new HandshakePacket();
        // 使用ByteBuffer处理字节顺序
        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);

        // 1. 验证包头
        if (buffer.get() != (byte) HEADER_LOW || buffer.get() != (byte) HEADER_HIGH) {
            packet.Validation=false;
            throw new InvalidPacketException("Invalid packet header");
        }

        // 2. 验证命令ID
        int cmdId = buffer.getShort() & 0xFFFF;
        packet.cmdid=cmdId;
        Log.d("TAG", "parse11: "+cmdId);
        if (cmdId != CMD_ID) {
        }

        // 3. 验证命令类型
        int cmdType = buffer.get() & 0xFF;
        if (cmdType != CMD_TYPE) {
        }



        // global_cnt (小端序)
        packet.globalCnt = buffer.getShort() & 0xFFFF;

        // 验证总长度
        int totalLength = buffer.get() & 0xFF;
        if (totalLength != PACKET_LENGTH) {
        }
//门锁状态上报
        if (cmdId==1027){
            int lock_status=buffer.get();
            packet.lock_status=lock_status;
            int door_status=buffer.get();
            packet.door_status=door_status;
            packet.timestamp=   buffer.getDouble();
            int exception_code=buffer.get();
            packet.exception_code=exception_code;
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }
//门锁状态查询回复
        if (cmdId==1026){
            int lock_status=buffer.get();
            packet.lock_status=lock_status;
            int door_status=buffer.get();
            packet.door_status=door_status;
            packet.timestamp=   buffer.getDouble();
            int exception_code=buffer.get();
            packet.exception_code=exception_code;
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }
//门状态查询回复
        if (cmdId==58885){
// 创建用于接收32字节的数组
            byte[] cpuId = new byte[32];
            buffer.get(cpuId, 0, 32); // 参数：目标数组, 起始位置, 读取长度
// 创建用于接收32字节的数组
            byte[] sn = new byte[32];

            buffer.get(sn, 0, 32); // 参数：目标数组, 起始位置, 读取长度
            for (int i = 0; i < sn.length; i++) {
                Log.d("TAG", "parse231: "+sn[i]);
            }
            packet.deviceSN=new String(sn, StandardCharsets.UTF_8);
            float leftweight=buffer.getFloat();
            float rightweight=buffer.getFloat();
            double time=buffer.getDouble();
            float bootCount=buffer.getFloat();
            int lockOnline= buffer.get()& 0xFF;
            int nc= buffer.get()& 0xFF;
            int no= buffer.get()& 0xFF;
            packet.door_det=buffer.get()& 0xFF;
            int relay= buffer.get()& 0xFF;
            int vout= buffer.get()& 0xFF;
            int temperature= buffer.get()& 0xFF;
            int udisk= buffer.get()& 0xFF;
            int receivedCrc1 = buffer.getShort() & 0xFFFF;
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }

        //供电状态上报
        if (cmdId==1793){
            int status=buffer.get()& 0xFF;
packet.status=status;
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }
        //设置MAC
        if (cmdId==58887){
            int mac_result=buffer.get()& 0xFF;
packet.mac_result=mac_result;
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }
        //获取MAC
        if (cmdId==58888){
//            String mac=buffer.get()& 0xFF;

            byte[] mac = new byte[18];

            buffer.get(mac, 0, 18); // 参数：目标数组, 起始位置, 读取长度
            for (int i = 0; i < mac.length; i++) {
                Log.d("TAG", "parse231: "+mac[i]);
            }
            packet.deviceSN=new String(mac, StandardCharsets.UTF_8);


packet.mac=new String(mac, StandardCharsets.UTF_8);
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }

        //对时回复
        if (cmdId==514){
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }
        //设置柜方向
        if (cmdId==58886){
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }
        //设置SN号
        if (cmdId==58882){
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }

        //目标温度设置回复
        if (cmdId==1281){
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }

        //实时温度读取返回
        if (cmdId==1283){
            packet.timestamp=buffer.getDouble();
            packet.temp_now=buffer.get();

            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }

        //实时温度读取返回
        if (cmdId==58881){
            int receivedCrc1 = buffer.getShort() & 0xFFFF;

            // 验证CRC (示例中省略实际CRC计算)
            if (!verifyCrc(data, receivedCrc1)) {
                packet.Validation=false;
                throw new InvalidPacketException("CRC verification failed");
            }
        }

//心跳
        if (cmdId==513){
            Log.d("TAG", "parse111: ");
        // CRC校验 (小端序)
        int receivedCrc1 = buffer.getShort() & 0xFFFF;

        // 验证CRC (示例中省略实际CRC计算)
        if (!verifyCrc(data, receivedCrc1)) {
            packet.Validation=false;
            throw new InvalidPacketException("CRC verification failed");
        }}

        //重力数据
        if (cmdId==769){
            Log.d("TAG", "pars11122322e111: ");

            //左传感器重力数据
            packet.weight_left=    buffer.getFloat();
            packet.weight_right=   buffer.getFloat();
            packet.timestamp=   buffer.getDouble();

        // CRC校验 (小端序)
        int receivedCrc1 = buffer.getShort() & 0xFFFF;

        // 验证CRC (示例中省略实际CRC计算)
        if (!verifyCrc(data, receivedCrc1)) {
            packet.Validation=false;
            throw new InvalidPacketException("CRC verification failed");
        }
        }

        //握手回包
        if (cmdId==257){
        packet.appId = buffer.get() & 0xFF;
        packet.hardwareStatus = buffer.get() & 0xFF;
        packet.protocolVersion = buffer.get() & 0xFF;

        // 软件版本 (32字节)
        byte[] softwareVerBytes = new byte[32];
        buffer.get(softwareVerBytes);
        packet.softwareVersion = new String(softwareVerBytes).trim();

        // 设备SN (32字节)
        byte[] devSnBytes = new byte[32];
        buffer.get(devSnBytes);
        packet.deviceSN = new String(devSnBytes).trim();

        // 端口配置
        packet.weightPort = 7000 + (buffer.get() & 0xFF);
        packet.lockPort = 7000 + (buffer.get() & 0xFF);
        packet.tempControlPort = 7000 + (buffer.get() & 0xFF);
        packet.generalPort = 7000 + (buffer.get() & 0xFF);

        // 功能标志 (4字节)
        packet.functionFlags = new byte[4];
        buffer.get(packet.functionFlags);

        // CRC校验 (小端序)
        int receivedCrc = buffer.getShort() & 0xFFFF;

        // 验证CRC (示例中省略实际CRC计算)
        if (!verifyCrc(data, receivedCrc)) {
            packet.Validation=false;
            throw new InvalidPacketException("CRC verification failed");
        }}

        return packet;
    }
    public static String toHexString(byte[] bytes, String delimiter) {
        if (bytes == null) throw new IllegalArgumentException("Input cannot be null");
        if (bytes.length != 32) throw new IllegalArgumentException("Input must be 32 bytes");

        final char[] hexArray ="0123456789abcdef".toCharArray();

        StringBuilder sb = new StringBuilder(64 + (delimiter != null ? 31 * delimiter.length() : 0));

        for (int i = 0; i < bytes.length; i++) {
            int v = bytes[i] & 0xFF;
            sb.append(hexArray[v >>> 4]);
            sb.append(hexArray[v & 0x0F]);

            if (delimiter != null && i < bytes.length - 1) {
                sb.append(delimiter);
            }
        }

        return sb.toString();
    }

    private static boolean verifyCrc(byte[] data, int receivedCrc) {
        int crc = Crc16Utils.calcCrc16(Arrays.copyOfRange(data, 0, data.length-2));
        Log.d("TAG", "receivedCrc: "+receivedCrc+"  crc:"+crc);
        if (crc==receivedCrc){
            return true;

        }
        return false;
    }



    public static class HandshakePacket {
        int status;
        int mac_result;
        //门锁状态上报
        int lock_status;
        int door_status;
        int exception_code;
String mac;
int door_det;

        public boolean Validation=true;
        public int globalCnt;
        public int cmdid;
        public int appId;
        public int hardwareStatus;
        public int protocolVersion;
        public String softwareVersion;
        public String deviceSN;
        public int weightPort;
        public int lockPort;
        public int tempControlPort;
        public int generalPort;
        public byte[] functionFlags;
        //重力数据
        float weight_left;
        float weight_right;
        double timestamp;
        byte temp_now;

        // 功能标志解析方法
        public boolean hasTemperatureControl() {
            return (functionFlags[0] & 0x01) != 0; // 第1位：温控
        }

        public boolean hasBackupBattery() {
            return (functionFlags[0] & 0x02) != 0; // 第2位：备用电池
        }

        public boolean hasIpcReset() {
            return (functionFlags[0] & 0x04) != 0; // 第3位：IPC硬复位
        }

        public boolean hasControlBoardReset() {
            return (functionFlags[0] & 0x08) != 0; // 第4位：控制板硬复位
        }
    }

    public static class InvalidPacketException extends Exception {
        public InvalidPacketException(String message) {
            super(message);
        }
    }

}